import { Game, game, ISchedulable } from "cc";
import { singleton } from "../decorator";
import Socket from "./Socket";


@singleton
export default class SocketManager implements IManager, ISchedulable {
    public static readonly instance: SocketManager;
    id?: string;
    uuid?: string;

    launched: boolean;

    private _socket: Socket;
    private _isGameHide: boolean;

    private _msgMap: Map<string|number, IProto>;

    constructor() {
        this.id = "SocketManager_ID";
        this.uuid = "SocketManager_UUID"
        this.initData();
        this.launched = true;
    }
    

    public connectWebSocket(url: string): void {
        if(this._socket.isConnect()) return ;
        this._socket.connect(url);
    }


    public reconnectWebSocket(): void {
        if(this._isGameHide) return;
        if(this._socket.isConnect()) return;
        this._socket.reconnectImmediately();
    } 

    public sendMessage(msgId: int, content: any): void {
        if(!this._socket.isConnect()) {
            if(!this._socket.isConnecting) {
                this._socket.reconnectImmediately();
                return;
            }
        }
        let proto = this.getProto(msgId);
        this._socket.send(msgId, content, proto);
        
    }

    public  registerMsgRouter(msgId: int, msg: IProto): void {
        this._msgMap.set(msgId, msg);
    }

    public getProto(msgId: int): IProto {
        return this._msgMap.get(msgId);
    }

    public clear(): void {
        this._socket = null;
        this._msgMap.clear();
        this._msgMap = null;
        this.unregistEvent();
    }

    private initData(): void {
        if(this.launched) return;
        this._isGameHide = false;
        this._msgMap = new Map();
        this._socket = new Socket();
        this.registEvent();
    }

    private registEvent(): void {
        game.on(Game.EVENT_HIDE, this.onHide, this);
        game.on(Game.EVENT_SHOW, this.onShow, this);
    }

    private unregistEvent(): void {
        game.off(Game.EVENT_HIDE, this.onHide, this);
        game.off(Game.EVENT_SHOW, this.onShow, this);
    }

    private onHide(): void {
        // 游戏进入后台
        this._isGameHide = true;
    }

    private onShow(): void {
        // 游戏进入前台
        this._isGameHide = false;
        this.reconnectWebSocket();
    }
}